package main

import (
	"fmt"
	"math/rand"
	"sort"
	"strings"
)

// 10_map
// 是一种无序的key-value的数据结构，Go语言中的map是引用类型，必须初始化才能使用
func main() {
	// 定义
	var a map[string]int
	// true
	fmt.Println(a == nil)
	// map的初始化
	a = make(map[string]int, 10)
	// false
	fmt.Println(a == nil)
	// map中添加键值对
	a["count"] = 100
	a["score"] = 200
	fmt.Printf("a:%#v\n", a)
	// 声明map的同时完成初始化
	b := map[int]bool{
		1: true,
		2: false,
	}
	fmt.Printf("a:%#v\n", b)

	// c没有初始化，不能直接操作！
	//01_var c 10_map[int]int
	//c[100] = 200
	//fmt.Println(c)
	// 判断某个键不存在
	var scoreMap = make(map[string]int, 8)
	scoreMap["xinKong"] = 100
	scoreMap["nancy"] = 90
	// 判断张三在不在map
	value, ok := scoreMap["张三"]
	if ok {
		fmt.Println("张三在map中", value)
	} else {
		fmt.Println("查无此人！")
	}

	// map的遍历
	// 顺序和添加的顺序无关
	for k, v := range scoreMap {
		fmt.Println(k, v)
	}
	// 只遍历map中的key
	for k := range scoreMap {
		fmt.Println(k)
	}
	// 只遍历map中的value
	for _, v := range scoreMap {
		fmt.Println(v)
	}

	// 删除 nancy这个键值对
	delete(scoreMap, "nancy")
	fmt.Println(scoreMap)

	// 按照固定顺序遍历map
	var scoreMap2 = make(map[string]int, 100)
	for i := 0; i < 50; i++ {
		key := fmt.Sprintf("stu%02d", i)
		value := rand.Intn(100) // 0-99随机整数
		scoreMap2[key] = value
	}
	for k, v := range scoreMap2 {
		fmt.Println(k, v)
	}
	// 按照key从小到大的顺序
	// 1.先取出所有的key存放到切片
	keys := make([]string, 0, 100)
	for k := range scoreMap2 {
		keys = append(keys, k)
	}
	// 2.对key做排序
	sort.Strings(keys)
	// 3.按照排序后的key进行排序
	for _, v := range keys {
		fmt.Println(v, scoreMap2[v])
	}

	// 元素类型为map的切片
	// 先完成切片的初始化
	var mapSlice = make([]map[string]int, 8, 8)
	// 再完成内部map元素的初始化
	mapSlice[0] = make(map[string]int, 8)
	mapSlice[0]["account"] = 100
	fmt.Println(mapSlice)

	// 值为切片的map
	// 先完成map的初始化
	var sliceMap = make(map[string][]int, 8)
	// 再完成切片的初始化
	sliceMap["中国"] = make([]int, 8)
	sliceMap["中国"][0] = 100
	sliceMap["中国"][1] = 200
	sliceMap["中国"][2] = 300

	// 统计一个字符串中每个单词出现的次数
	// how do you do
	// 0.定义一个map[string]int
	var s = "how do you do"
	var wordCount = make(map[string]int, 10)
	// 1.字符串中都有哪些单词
	words := strings.Split(s, " ")
	// 2.遍历单词做统计
	for _, word := range words {
		v, ok := wordCount[word]
		if ok {
			// map中有这个单词的统计记录
			wordCount[word] = v + 1
		} else {
			// map中没有这个单词的统计记录
			wordCount[word] = 1
		}
	}
	for k, v := range wordCount {
		fmt.Println(k, v)
	}
}
